package com.hotel.BL;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;




import data.Charge;
import data.Folio;
import data.Payment;
import data.SubPayment;

public class SubPaymentLogic extends AbstractBL {
	public SubPaymentLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}
	
	public SubPayment GetSubPayment(long id) {
      Key key = KeyFactory.createKey(EntityName.SubPayment, id);
		try {
			Entity lang = datastore.get(key);
			SubPayment c = new SubPayment();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}

public List<SubPayment> GetAllSubPayment(long parentPaymentId, long hotelId )
{
	Query q = new Query(EntityName.SubPayment);

	Filter filterHotel = new FilterPredicate("HotelId",
			FilterOperator.EQUAL,hotelId);
	Filter filterpPayment = new FilterPredicate("ParentPayment",
			FilterOperator.EQUAL,  String.valueOf(parentPaymentId));
//	Filter filterfId = new FilterPredicate("folioId",
//			FilterOperator.EQUAL, folioId);

	Filter filter = CompositeFilterOperator.and(filterHotel, filterpPayment);

	q.setFilter(filter);

	return GetList(datastore.prepare(q).asList(
			FetchOptions.Builder.withDefaults()));
	
}


public List<SubPayment> GetList(List<Entity> entities) {
	List<SubPayment> list = new ArrayList<SubPayment>();
	if(entities!=null)
	for (Entity e : entities) {
		SubPayment a = new SubPayment();
		a.setEntity(e);
		list.add(a);
	}
	return list;
}

public List<SubPayment> RoutePayment(String PaymentId,double amount, long folioId,long hotelId) throws EntityNotFoundException{

	double sumAmount = amount;
	@SuppressWarnings("unused")
	double Result =0;
	
	String[] pmIdArray = PaymentId.trim().split(",");
	
	List<SubPayment> list = new ArrayList<SubPayment>();
	for(int i = 0;i<pmIdArray.length;i++)
	{
		
		if(sumAmount == 0)
		{
			break;
		}
		List<SubPayment> p = GetAllSubPayment(Long.parseLong(pmIdArray[i]),hotelId);
		Folio f= new FolioLogic(req,resp).GetFolio(folioId);
		double chargeAmount =0;
		double paymentAmount=0;
		
		for(Charge c : f.getCharge() )
		{
			chargeAmount +=(c.getChargeAmount()+c.getTax());
		}
		if(f.getPaymentString()!=null){
		String [] paymentList = f.getPaymentString().trim().split(",");
		for(int n =0;n<paymentList.length;n++)
		{
			SubPayment ps = GetSubPayment(Long.parseLong(paymentList[n]));
			paymentAmount +=ps.getAmount();
		}
		}else
		{
			paymentAmount=0;
		}
		
		SubPayment sb = new SubPayment();
		
		Payment pm = new PaymentLogic(req,resp).GetPayment(Long.parseLong(pmIdArray[i]));
		
		
		
		if(p.isEmpty() == true)
		{
			
			sb.setAmount(pm.getAmount());
			sb.setHotelId(pm.getHotelId());
			sb.setParentPaymentString(String.valueOf(pm.getId()));
			
			Key ks = datastore.put(sb.getEntity());
			sb.setId(ks.getId());
			sb.setKey(ks);
			
			
			if((sb.getAmount()-sumAmount ) == 0 )
			{
				
				Result= sb.getAmount()-sumAmount;
				SubPayment subPay = new SubPayment();
				subPay.setAmount(sumAmount);
				subPay.setHotelId(sb.getHotelId());
				subPay.setFolioId(folioId);
				subPay.setParentPaymentString(sb.getParentPaymentString());
				
				Key ksp = datastore.put(subPay.getEntity());
				subPay.setId(ksp.getId());
				subPay.setKey(ksp);
				
				Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
				datastore.delete(key);
				
				if(f.getPaymentString() != null){
					f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
				}else
				{
					f.setPaymentString(String.valueOf(subPay.getId()));
				}
				
				Key kf = datastore.put(f.getEntity());
				f.setId(kf.getId());
				f.setKey(kf);
				sumAmount =0;
			}
			else if(sb.getAmount()>sumAmount)
			{
				
				for(int n =0;n<2;n++)
				{
					SubPayment subPay = new SubPayment();
					if(n==1)
					{
						if(sumAmount >chargeAmount)
						{
							subPay.setAmount(sb.getAmount()-sumAmount);
						}else
						{
							subPay.setAmount(sb.getAmount()-(chargeAmount -paymentAmount));
						}
					}else
					{
						if(sumAmount >chargeAmount)
						{
							subPay.setAmount(sumAmount);	
						}else
						{
							subPay.setAmount(chargeAmount -paymentAmount);	
						}
						subPay.setFolioId(folioId);
					}
					
					subPay.setHotelId(sb.getHotelId());
					
					subPay.setParentPaymentString(sb.getParentPaymentString());
					
					Key ksp = datastore.put(subPay.getEntity());
					subPay.setId(ksp.getId());		
					subPay.setKey(ksp);			
					
					if(n==0)
					{
						
						if(f.getPaymentString() != null){
							f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
						}else
						{
							f.setPaymentString(String.valueOf(subPay.getId()));
						}
						
						Key kf = datastore.put(f.getEntity());
						f.setId(kf.getId());
						f.setKey(kf);
					}
					
				}
				
				Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
				datastore.delete(key);
			
				
			
			
				sumAmount =0;
			}
			else if(sb.getAmount()<sumAmount)
			{
				if(sb.getAmount() < 0)
				{
					for(int n =0;n<2;n++)
					{
						SubPayment subPay = new SubPayment();
						if(n==1)
						{
							subPay.setAmount(sb.getAmount()-(chargeAmount -paymentAmount));
						}else
						{
							subPay.setAmount(chargeAmount -paymentAmount);	
							subPay.setFolioId(folioId);
						}
						
						subPay.setHotelId(sb.getHotelId());
						
						subPay.setParentPaymentString(sb.getParentPaymentString());
						
						Key ksp = datastore.put(subPay.getEntity());
						subPay.setId(ksp.getId());
						subPay.setKey(ksp);
						
						
						if(n==0)
						{
							
							if(f.getPaymentString() != null){
								f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
							}else
							{
								f.setPaymentString(String.valueOf(subPay.getId()));
							}
							
							Key kf = datastore.put(f.getEntity());
							f.setId(kf.getId());
							f.setKey(kf);
						}
						if(sb.getAmount()-(chargeAmount -paymentAmount)==0)
						{
							break;
						}
					}
					
					Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
					datastore.delete(key);
				
					
				}else{
					sumAmount= amount-sb.getAmount();
					
					SubPayment subPay = new SubPayment();
					subPay.setAmount(sb.getAmount());	
					subPay.setHotelId(sb.getHotelId());
					subPay.setFolioId(folioId);
					subPay.setParentPaymentString(sb.getParentPaymentString());
					
					Key ksp = datastore.put(subPay.getEntity());
					subPay.setId(ksp.getId());
					subPay.setKey(ksp);
					
					if(f.getPaymentString() != null){
						f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
					}else
					{
						f.setPaymentString(String.valueOf(subPay.getId()));
					}
				
					Key kf = datastore.put(f.getEntity());
					f.setId(kf.getId());
					f.setKey(kf);
					
					
					Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
					datastore.delete(key);
					}
			}
			
		
		}
		else
		{
			double chFolio = 0;
			double PaymentAmountSum =0;
			for(SubPayment sp: p)
			{
				chFolio=sp.getFolioId();
				if(chFolio == 0)
				{
					PaymentAmountSum+=sp.getAmount();
					Key key = KeyFactory.createKey(EntityName.SubPayment, sp.getId());
					datastore.delete(key);
				}
				
			}

			
			sb.setAmount(PaymentAmountSum);
			sb.setHotelId(pm.getHotelId());
			sb.setParentPaymentString(String.valueOf(pm.getId()));
			
			Key ks = datastore.put(sb.getEntity());
			sb.setId(ks.getId());
			sb.setKey(ks);
			
			
			if((sb.getAmount()-sumAmount ) == 0 )
			{
				Result= sb.getAmount()-sumAmount;
				SubPayment subPay = new SubPayment();
				subPay.setAmount(sumAmount);
				subPay.setHotelId(sb.getHotelId());
				subPay.setFolioId(folioId);
				subPay.setParentPaymentString(sb.getParentPaymentString());
				
				Key ksp = datastore.put(subPay.getEntity());
				subPay.setId(ksp.getId());
				subPay.setKey(ksp);
				
				Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
				datastore.delete(key);
				
				if(f.getPaymentString() != null){
					f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
				}else
				{
					f.setPaymentString(String.valueOf(subPay.getId()));
				}
				
				Key kf = datastore.put(f.getEntity());
				f.setId(kf.getId());
				f.setKey(kf);
				
				sumAmount=0;
			}
			else if(sb.getAmount()>sumAmount)
			{
				
				
		
				for(int n =0;n<2;n++)
				{
					SubPayment subPay = new SubPayment();
					if(n==1)
					{
						if(sumAmount >chargeAmount)
						{
							subPay.setAmount(sb.getAmount()-sumAmount);
						}else
						{
							subPay.setAmount(sb.getAmount()-(chargeAmount -paymentAmount));
						}
						
					}else
					{
						if(sumAmount >chargeAmount)
						{
							subPay.setAmount(sumAmount);	
						}else
						{
							subPay.setAmount(chargeAmount -paymentAmount);	
						}	
						subPay.setFolioId(folioId);
					}
					
					subPay.setHotelId(sb.getHotelId());
					
					subPay.setParentPaymentString(sb.getParentPaymentString());
					
					Key ksp = datastore.put(subPay.getEntity());
					subPay.setId(ksp.getId());
					subPay.setKey(ksp);
					
					
					if(n==0)
					{
						
						if(f.getPaymentString() != null){
							f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
						}else
						{
							f.setPaymentString(String.valueOf(subPay.getId()));
						}
						
						Key kf = datastore.put(f.getEntity());
						f.setId(kf.getId());
						f.setKey(kf);
					}
					
				}
				
				Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
				datastore.delete(key);
			
				
			
			
				sumAmount =0;
			}
			else if(sb.getAmount()<sumAmount)
			{
				if(sb.getAmount() < 0)
				{
					for(int n =0;n<2;n++)
					{
						SubPayment subPay = new SubPayment();
						if(n==1)
						{
							subPay.setAmount(sb.getAmount()-(chargeAmount -paymentAmount));
						}else
						{
							subPay.setAmount(chargeAmount -paymentAmount);	
							subPay.setFolioId(folioId);
						}
						
						subPay.setHotelId(sb.getHotelId());
						
						subPay.setParentPaymentString(sb.getParentPaymentString());
						
						Key ksp = datastore.put(subPay.getEntity());
						subPay.setId(ksp.getId());
						subPay.setKey(ksp);
						
						
						if(n==0)
						{
							
							if(f.getPaymentString() != null){
								f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
							}else
							{
								f.setPaymentString(String.valueOf(subPay.getId()));
							}
							
							Key kf = datastore.put(f.getEntity());
							f.setId(kf.getId());
							f.setKey(kf);
						}
						if(sb.getAmount()-(chargeAmount -paymentAmount)==0)
						{
							break;
						}
					}
					
					Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
					datastore.delete(key);
				
					
				}else{
					sumAmount= amount-sb.getAmount();
					
					SubPayment subPay = new SubPayment();
					subPay.setAmount(sb.getAmount());	
					subPay.setHotelId(sb.getHotelId());
					subPay.setFolioId(folioId);
					subPay.setParentPaymentString(sb.getParentPaymentString());
					
					Key ksp = datastore.put(subPay.getEntity());
					subPay.setId(ksp.getId());
					subPay.setKey(ksp);
					
					if(f.getPaymentString() != null){
						f.setPaymentString(f.getPaymentString()+","+String.valueOf(subPay.getId()));
					}else
					{
						f.setPaymentString(String.valueOf(subPay.getId()));
					}
				
					Key kf = datastore.put(f.getEntity());
					f.setId(kf.getId());
					f.setKey(kf);
					
					
					Key key = KeyFactory.createKey(EntityName.SubPayment, sb.getId());
					datastore.delete(key);
					}
			}
			
		
	
		
		}
		list.add(sb);
	}
	
	return list;
}

public void DeleteSubPayment(long SubPayment) {
	Key key = KeyFactory.createKey(EntityName.SubPayment, SubPayment);
	datastore.delete(key);
	
}

}
